<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted, reactive } from 'vue';
import { LocateSetData, CubeModelConfig } from '@/utils/appCommon/appCommonOptions/aeLocateConfigModel';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import { computeScaleRate } from "@/views/apply/locateAnalysis/component/utils/commonThree";
interface Props {
  locateSetting: LocateSetData;
  renderParams: {
    width: number;
    height: number;
    viewMode?: number;
  };
  searchParams: Record<string, any>;
}

const props = defineProps<Props>();

// Three.js核心对象
let scene: THREE.Scene | null = null;
let camera: THREE.PerspectiveCamera | null = null;
let renderer: THREE.WebGLRenderer | null = null;
let controls: OrbitControls | null = null;
let raycaster: THREE.Raycaster | null = null;
let mouse: THREE.Vector2 | null = null;

// 模型相关
let customGridMesh: THREE.Mesh | null = null;
let axisLineMeshes: THREE.Object3D[] = [];
let axisTextMeshes: THREE.Object3D[] = [];
let axisLabelFont: any = null;

// 状态管理
const threeBoxRef = ref();
const threeData = reactive({
  width: 600,
  height: 600,
  bgColor: '#f0f4f8',
  scaleRate: 1 // 用于实际尺寸和3D尺寸之间的转换
});
const mousePosition = reactive({
  x: 0,
  y: 0,
  z: 0
});

// 传感器数据结构
const sensors = ref<Array<{
  id: number|string;
  x: number;
  y: number;
  z: number;
  cube: THREE.Mesh;
  dynamicStyle: {
    left: string;
    top: string;
    display: string;
  };
}>>([]);

// 传感器编号计数器
let sensorCounter = 0;

// 初始化Three.js场景
function initThree() {
  if (!threeBoxRef.value || !props.locateSetting) return;

  // 清理之前的场景
  cleanup();

  // 创建新的场景
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera();
  renderer = new THREE.WebGLRenderer({ antialias: true });

  // 更新threeData的尺寸
  threeData.width = props.renderParams.width || 600;
  threeData.height = props.renderParams.height || 600;

  // 设置渲染器
  renderer.setSize(threeData.width, threeData.height);
  renderer.setPixelRatio(window.devicePixelRatio);
  threeBoxRef.value.innerHTML = '';
  threeBoxRef.value.appendChild(renderer.domElement);

  // 设置背景色
  scene.background = new THREE.Color(threeData.bgColor);

  // 设置相机
  const cameraY = threeData.width > 400 ? threeData.width : 400;
  camera.position.set(0, -cameraY, 0); // 初始相机位置
  camera.lookAt(scene.position); // 指向原点
  camera.aspect = threeData.width / threeData.height;
  camera.updateProjectionMatrix();

  // 创建轨道控制器
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
  controls.addEventListener('change', () => {
    updateAllTextPosition();
    render();
  });

  // 添加光源
  const light = new THREE.DirectionalLight(0xffffff, 1);
  light.position.set(0, threeData.width, threeData.height);
  scene.add(light);

  // 添加环境光
  const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight);

  // 创建辅助工具
  raycaster = new THREE.Raycaster();
  mouse = new THREE.Vector2();

  // 添加鼠标移动监听
  window.addEventListener('mousemove', listenMouseMove);

  // 初始化立方体网格
  createCustomGrid();

  // 创建坐标轴
  createAxis();

  // 添加传感器
  setTimeout(() => {
    addExampleSensors();
    // createSensorBoxes();
  }, 500);
}

// 获取立方体尺寸（考虑缩放）
function getCubeDimensions() {
  const modelConfig = props.locateSetting?.config?.modelConfig as CubeModelConfig;
  const xRange = modelConfig?.xRange || 1000;
  const yRange = modelConfig?.yRange || 1000;
  const zRange = modelConfig?.zRange || 1000;

  // 计算缩放率，使用最大尺寸作为基准
  const maxDimension = Math.max(xRange, yRange, zRange);
  const scaleRate = computeScaleRate(maxDimension, 200); // 200作为比较尺寸
  threeData.scaleRate = scaleRate;

  // 转换为3D视图中的尺寸
  return {
    physicalXRange: xRange,
    physicalYRange: yRange,
    physicalZRange: zRange,
    xRange: Math.max(xRange / scaleRate, 1),
    yRange: Math.max(yRange / scaleRate, 1),
    zRange: Math.max(zRange / scaleRate, 1),
    scaleRate
  };
}

// 创建立方体网格
function createCustomGrid() {
  if (!scene) return;

  // 清理旧模型
  if (customGridMesh) {
    scene.remove(customGridMesh);
  }

  // 获取缩放后的尺寸
  const { xRange, yRange, zRange } = getCubeDimensions();

  // 创建立方体几何体
  const cubeGeometry = new THREE.BoxGeometry(xRange, yRange, zRange, 1, 1, 1);
  const material = new THREE.MeshBasicMaterial({
    color: 0xdadada,
    wireframe: true, // 使用线框模式
    transparent: true,
    opacity: 0.8
  });

  customGridMesh = new THREE.Mesh(cubeGeometry, material);

  // 调整位置，使立方体中心在原点
  customGridMesh.position.set(0, 0, 0);

  // 添加到场景
  scene.add(customGridMesh);

  render();
}

// 创建坐标轴
function createAxis() {
  if (!scene) return;

  // 清除现有的坐标轴
  if (axisLineMeshes.length > 0) {
    axisLineMeshes.forEach(item => {
      item.removeFromParent();
    });
    axisLineMeshes = [];
  }

  if (axisTextMeshes.length > 0) {
    axisTextMeshes.forEach(item => {
      item.removeFromParent();
    });
    axisTextMeshes = [];
  }

  // 加载字体
  const fontLoader = new FontLoader();
  fontLoader.load('/public/threefont.json', function(font) {
    axisLabelFont = font;
    createAxisHelper(font);
  });
}

// 创建坐标轴辅助
function createAxisHelper(font: any) {
  if (!scene) return;

  // 获取缩放后的尺寸
  const { xRange, yRange, zRange } = getCubeDimensions();
  const xhalf = xRange / 2;
  const yhalf = yRange / 2;
  const zhalf = zRange / 2;

  // 创建材质
  const materialX = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 红色X轴
  const materialY = new THREE.LineBasicMaterial({ color: 0x00ff00 }); // 绿色Y轴
  const materialZ = new THREE.LineBasicMaterial({ color: 0x0000ff }); // 蓝色Z轴

  // 计算轴范围
  const xmin = 0;
  const xmax = xRange;
  const xstep = xmax / 10;

  const ymin = 0;
  const ymax = yRange;
  const ystep = ymax / 10;

  const zmin = 0;
  const zmax = zRange;
  const zstep = zmax / 10;

  // X轴刻度和标签
  let xcount = 0;
  for (let i = xmin; i <= xmax; i += xstep) {
    if (xcount % 2 === 0 && i > 0) {
      // 根据缩放率计算物理尺寸标签
      const physicalValue = Math.round(i * threeData.scaleRate);
      const textLabel = physicalValue.toString();
      const textGeometry = new TextGeometry(textLabel, {
        font: font,
        size: xstep / 4,
        height: 0.1
      });
      const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
      const textMesh = new THREE.Mesh(textGeometry, textMaterial);
      textMesh.position.set(i - xhalf, -0.5 - yhalf, 0.2 - zhalf);
      axisTextMeshes.push(textMesh);
      scene?.add(textMesh);
    }
    xcount++;
  }

  // Y轴刻度和标签
  for (let i = ymin; i <= ymax; i += ystep) {
    if (i > 0) {
      // 根据缩放率计算物理尺寸标签
      const physicalValue = Math.round(i * threeData.scaleRate);
      const textLabel = physicalValue.toString();
      const textGeometry = new TextGeometry(textLabel, {
        font: font,
        size: ystep / 4,
        height: 0.1
      });
      const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
      const textMesh = new THREE.Mesh(textGeometry, textMaterial);
      textMesh.position.set(-0.5 - xhalf, i - yhalf, 0.2 - zhalf);
      axisTextMeshes.push(textMesh);
      scene?.add(textMesh);
    }
  }

  // Z轴刻度和标签
  for (let i = zmin; i <= zmax; i += zstep) {
    if (i > 0) {
      // 根据缩放率计算物理尺寸标签
      const physicalValue = Math.round(i * threeData.scaleRate);
      const textLabel = physicalValue.toString();
      const textGeometry = new TextGeometry(textLabel, {
        font: font,
        size: zstep / 4,
        height: 0.1
      });
      const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
      const textMesh = new THREE.Mesh(textGeometry, textMaterial);
      textMesh.position.set(-0.5 - xhalf, 0.2 - yhalf, i - zhalf);
      axisTextMeshes.push(textMesh);
      scene?.add(textMesh);
    }
  }

  // XYZ轴线
  // X轴
  const xAxisGeometry = new THREE.BufferGeometry();
  const xAxisPositions = new Float32Array([
    xmin, 0, 0,
    xmax + xstep, 0, 0
  ]);
  xAxisGeometry.setAttribute('position', new THREE.BufferAttribute(xAxisPositions, 3));
  const xAxisLine = new THREE.Line(xAxisGeometry, materialX);
  xAxisLine.position.set(-xhalf, -yhalf, -zhalf);
  axisLineMeshes.push(xAxisLine);
  scene?.add(xAxisLine);

  // Y轴
  const yAxisGeometry = new THREE.BufferGeometry();
  const yAxisPositions = new Float32Array([
    0, ymin, 0,
    0, ymax + ystep, 0
  ]);
  yAxisGeometry.setAttribute('position', new THREE.BufferAttribute(yAxisPositions, 3));
  const yAxisLine = new THREE.Line(yAxisGeometry, materialY);
  yAxisLine.position.set(-xhalf, -yhalf, -zhalf);
  axisLineMeshes.push(yAxisLine);
  scene?.add(yAxisLine);

  // Z轴
  const zAxisGeometry = new THREE.BufferGeometry();
  const zAxisPositions = new Float32Array([
    0, 0, zmin,
    0, 0, zmax + zstep
  ]);
  zAxisGeometry.setAttribute('position', new THREE.BufferAttribute(zAxisPositions, 3));
  const zAxisLine = new THREE.Line(zAxisGeometry, materialZ);
  zAxisLine.position.set(-xhalf, -yhalf, -zhalf);
  axisLineMeshes.push(zAxisLine);
  scene?.add(zAxisLine);

  render();
}

// 平面坐标转换为3D坐标
function transferPlaneDataTo3dData(x: number, y: number, z: number): { x: number; y: number; z: number } {
  const { physicalXRange, physicalYRange, physicalZRange, scaleRate } = getCubeDimensions();

  // 计算缩放后的坐标，并调整到立方体中心
  const scaledX = (x / scaleRate) - (physicalXRange / 2 / scaleRate);
  const scaledY = (y / scaleRate) - (physicalYRange / 2 / scaleRate);
  const scaledZ = (z / scaleRate) - (physicalZRange / 2 / scaleRate);

  return { x: scaledX, y: scaledY, z: scaledZ };
}

// 创建传感器立方体
function createCubeItem(size: number): THREE.Mesh {
  const cubeGeometry = new THREE.BoxGeometry(size, size, size);
  const material = new THREE.MeshBasicMaterial({
    color: 0x0000ee
  });
  const cube = new THREE.Mesh(cubeGeometry, material);
  return cube;
}

// 创建传感器
function createSensorBoxes() {
  if (!scene || !props.locateSetting) return;

  // 清除旧的传感器
  sensors.value.forEach(item => {
    if (item.cube) {
      scene?.remove(item.cube);
    }
  });
  sensors.value = [];
  sensorCounter = 0;

  const sensorSettings = props.locateSetting.sensorSettings || [];

  // 从配置中创建传感器
  sensorSettings.forEach((sensorSetting: any, index: number) => {
    const x = sensorSetting.x || 0;
    const y = sensorSetting.y || 0;
    const z = sensorSetting.z || 0;

    const numer = index + 1;
    const id = sensorSetting.id || numer;

    // 计算3D坐标
    const cubexyz = transferPlaneDataTo3dData(x, y, z);

    // 创建立方体，使用缩放后的尺寸
    const cube = createCubeItem(Math.max(2, 5 / threeData.scaleRate));
    cube.position.set(cubexyz.x, cubexyz.y, cubexyz.z);
    scene?.add(cube);

    // 判断是否可见
    const isVisible = judgeSensorTextShow(cube);

    // 添加到传感器列表
    sensors.value.push({
      id,
      x,
      y,
      z,
      cube,
      dynamicStyle: {
        left: '0px',
        top: '0px',
        display: isVisible ? 'block' : 'none'
      }
    });
  });
  // 更新所有标签位置
  updateAllTextPosition();
  render();
}

// 添加示例传感器
function addExampleSensors() {
  if (!scene || !props.locateSetting) return;

  const modelConfig = props.locateSetting.config?.modelConfig as CubeModelConfig;
  const { physicalXRange, physicalYRange, physicalZRange } = getCubeDimensions();

  // 添加一些示例传感器
  addSensor(physicalXRange * 0.2, physicalYRange * 0.2, physicalZRange * 0.2);
  addSensor(physicalXRange * 0.8, physicalYRange * 0.3, physicalZRange * 0.5);
  addSensor(physicalXRange * 0.5, physicalYRange * 0.7, physicalZRange * 0.8);
  addSensor(physicalXRange * 0.3, physicalYRange * 0.9, physicalZRange * 0.4);

  render();
}

// 添加传感器
function addSensor(x: number, y: number, z: number, existingId?: number|string): number|string {
  if (!scene) return -1;

  const currentId = existingId || `sensor_${++sensorCounter}`;

  // 计算3D坐标
  const cubexyz = transferPlaneDataTo3dData(x, y, z);

  // 创建传感器立方体，使用缩放后的尺寸
  const cube = createCubeItem(Math.max(2, 5 / threeData.scaleRate));
  cube.position.set(cubexyz.x, cubexyz.y, cubexyz.z);
  scene.add(cube);

  // 判断是否可见
  const isVisible = judgeSensorTextShow(cube);

  // 添加传感器数据
  sensors.value.push({
    id: currentId,
    x,
    y,
    z,
    cube,
    dynamicStyle: {
      left: '0px',
      top: '0px',
      display: isVisible ? 'block' : 'none'
    }
  });

  // 更新标签位置
  updateTextPosition(sensors.value.length - 1, cube);

  render();
  return currentId;
}

// 删除传感器
function removeSensor(id: number|string): boolean {
  if (!scene) return false;

  const index = sensors.value.findIndex(sensor => sensor.id === id);
  if (index === -1) return false;

  // 移除3D对象
  scene.remove(sensors.value[index].cube);

  // 从数组中删除
  sensors.value.splice(index, 1);

  render();
  return true;
}

// 判断传感器标签是否显示
function judgeSensorTextShow(cube: THREE.Mesh): boolean {
  if (!camera || !scene) return true;
  // 简单实现：总是显示
  return true;
}

// 更新所有传感器标签位置
function updateAllTextPosition() {
  sensors.value.forEach((item, index) => {
    if (item.cube) {
      updateTextPosition(index, item.cube);
    }
  });
}

// 更新单个传感器标签位置
function updateTextPosition(index: number, cube: THREE.Mesh) {
  if (!camera) return;

  const vector = new THREE.Vector3();
  cube.getWorldPosition(vector);
  vector.project(camera);

  const x = (vector.x * 0.5 + 0.5) * threeData.width;
  const y = (-vector.y * 0.5 + 0.5) * threeData.height;

  if (sensors.value[index]) {
    sensors.value[index].dynamicStyle.left = `${x + 10}px`;
    sensors.value[index].dynamicStyle.top = `${y - 10}px`;
  }
}

// 监听鼠标移动
function listenMouseMove(event: MouseEvent) {
  if (!renderer || !camera || !raycaster || !mouse) return;

  const rect = renderer.domElement.getBoundingClientRect();
  const x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
  const y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

  mouse.set(x, y);
  raycaster.setFromCamera(mouse, camera);

  // 找出所有可交互的物体
  const intersectables: THREE.Object3D[] = [];
  if (customGridMesh) {
    intersectables.push(customGridMesh);
  }
  sensors.value.forEach(sensor => {
    intersectables.push(sensor.cube);
  });

  // 检查射线相交
  const intersects = raycaster.intersectObjects(intersectables, false);
  if (intersects.length > 0) {
    const intersection = intersects[0];
    const position = intersection.point;

    // 更新鼠标位置（转换为物理尺寸）
    const { physicalXRange, physicalYRange, physicalZRange, scaleRate } = getCubeDimensions();
    mousePosition.x = Number((position.x * scaleRate + physicalXRange / 2).toFixed(1));
    mousePosition.y = Number((position.y * scaleRate + physicalYRange / 2).toFixed(1));
    mousePosition.z = Number((position.z * scaleRate + physicalZRange / 2).toFixed(1));
  }
}

// 渲染
function render() {
  if (renderer && scene && camera) {
    renderer.render(scene, camera);
  }
}

// 调整渲染器大小
function resizeRenderer() {
  if (!renderer || !camera) return;

  threeData.width = props.renderParams.width || 600;
  threeData.height = props.renderParams.height || 600;

  renderer.setSize(threeData.width, threeData.height);
  camera.aspect = threeData.width / threeData.height;
  camera.updateProjectionMatrix();

  if (controls) {
    controls.update();
  }

  render();
  updateAllTextPosition();
}

// 清理资源
function cleanup() {
  if (renderer) {
    renderer.dispose();
  }
  if (scene) {
    scene.clear();
  }
  window.removeEventListener('mousemove', listenMouseMove);
  axisLineMeshes = [];
  axisTextMeshes = [];
  sensors.value = [];
  sensorCounter = 0;
}

// 监听locateSetting参数变化
watch(
  () => props.locateSetting,
  (newVal) => {
    if (newVal) {
      console.log('立方体定位配置参数变化:', newVal);
      initThree();
    }
  },
  { deep: true, immediate: true }
);

// 监听renderParams参数变化
watch(
  () => props.renderParams,
  (newVal) => {
    console.log('渲染参数变化:', newVal);
    resizeRenderer();
  },
  { deep: true }
);

// 监听searchParams参数变化
watch(
  () => props.searchParams,
  (newVal) => {
    console.log('搜索参数变化:', newVal);
    // 3D视图对searchParams变化的处理逻辑
  },
  { deep: true }
);

// 组件挂载
onMounted(() => {
  console.log('立方体定位组件已挂载');
  initThree();
});

// 组件卸载
onUnmounted(() => {
  console.log('立方体定位组件已卸载');
  cleanup();
});

// 暴露方法给父组件
defineExpose({
  addSensor,
  removeSensor,
  transferPlaneDataTo3dData,
  mousePosition
});
</script>

<template>
  <div
    class="cube-locate-container"
    :style="{
      width: `${renderParams.width}px`,
      height: `${renderParams.height}px`
    }"
  >
    <div class="title">
      鼠标: X={{ mousePosition.x.toFixed(1) }}mm, Y={{ mousePosition.y.toFixed(1) }}mm, Z={{ mousePosition.z.toFixed(1) }}mm
    </div>
    <div ref="threeBoxRef" class="three-container">
    </div>
    <!-- 传感器编号显示 -->
    <template v-for="(sensor, index) in sensors" :key="index">
      <div class="sensor-label" :style="sensor.dynamicStyle">
        {{ sensor.id }}
      </div>
    </template>
  </div>
</template>

<style scoped lang="scss">
.cube-locate-container {
  position: relative;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
}

.title {
  position: relative;
  top: 0;
  left: 0;
  z-index: 100;
  width: 100%;
  text-align: center;
  font-size: 11px;
  background-color: transparent;
}

.three-container {
  width: 100%;
  height: 100%;
  position: relative;
}

.sensor-label {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  display: inline-block;
  line-height: 1;
  color: orangered;
  font-size: 13px;
  pointer-events: none; /* 避免影响鼠标交互 */
}

:deep(canvas) {
  display: block;
  width: 100% !important;
  height: 100% !important;
}
</style>
